package rad.framework.uml2.classdiagram.edit.policies;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import rad.framework.mda.util.ModelUtil;
import rad.framework.uml2.classdiagram.edit.parts.ActorEditPart;
import rad.framework.uml2.classdiagram.edit.parts.Association2EditPart;
import rad.framework.uml2.classdiagram.edit.parts.Association3EditPart;
import rad.framework.uml2.classdiagram.edit.parts.Association4EditPart;
import rad.framework.uml2.classdiagram.edit.parts.Association5EditPart;
import rad.framework.uml2.classdiagram.edit.parts.AssociationEditPart;
import rad.framework.uml2.classdiagram.edit.parts.ClassEditPart;
import rad.framework.uml2.classdiagram.edit.parts.DependencyEditPart;
import rad.framework.uml2.classdiagram.edit.parts.EnumerationEditPart;
import rad.framework.uml2.classdiagram.edit.parts.EnumerationLiteralEditPart;
import rad.framework.uml2.classdiagram.edit.parts.GeneralizationEditPart;
import rad.framework.uml2.classdiagram.edit.parts.InterfaceEditPart;
import rad.framework.uml2.classdiagram.edit.parts.OperationEditPart;
import rad.framework.uml2.classdiagram.edit.parts.PackageEditPart;
import rad.framework.uml2.classdiagram.edit.parts.PropertyEditPart;
import rad.framework.uml2.classdiagram.edit.parts.UseCaseEditPart;
import rad.framework.uml2.classdiagram.part.UMLDiagramEditorPlugin;
import rad.framework.uml2.classdiagram.part.UMLVisualIDRegistry;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.commands.CreateCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.DeferredLayoutCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalConnectionEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Dependency;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.Relationship;
import org.eclipse.uml2.uml.UMLPackage;

/**
 * @generated
 */
public class PackageCanonicalEditPolicy extends CanonicalConnectionEditPolicy {

	/**
	 * @generated
	 */
	protected List getSemanticChildrenList() {
		List result = new LinkedList();
		EObject modelObject = ((View) getHost().getModel()).getElement();
		View viewObject = (View) getHost().getModel();
		EObject nextValue;
		int nodeVID;
		for (Iterator values = ((org.eclipse.uml2.uml.Package) modelObject)
				.getPackagedElements().iterator(); values.hasNext();) {
			nextValue = (EObject) values.next();
			nodeVID = UMLVisualIDRegistry
					.getNodeVisualID(viewObject, nextValue);
			switch (nodeVID) {
			case ClassEditPart.VISUAL_ID: {
				result.add(nextValue);
				break;
			}
			case EnumerationEditPart.VISUAL_ID: {
				result.add(nextValue);
				break;
			}
			case InterfaceEditPart.VISUAL_ID: {
				result.add(nextValue);
				break;
			}
			case ActorEditPart.VISUAL_ID: {
				result.add(nextValue);
				break;
			}
			case UseCaseEditPart.VISUAL_ID: {
				result.add(nextValue);
				break;
			}
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	protected boolean shouldDeleteView(View view) {
		return view.isSetElement() && view.getElement() != null
				&& view.getElement().eIsProxy();
	}

	/**
	 * @generated
	 */
	protected String getDefaultFactoryHint() {
		return null;
	}

	/**
	 * @generated
	 */
	protected List getSemanticConnectionsList() {
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	protected EObject getSourceElement(EObject relationship) {
		return null;
	}

	/**
	 * @generated
	 */
	protected EObject getTargetElement(EObject relationship) {
		return null;
	}

	/**
	 * @generated
	 */
	protected boolean shouldIncludeConnection(Edge connector,
			Collection children) {
		return false;
	}

	/**
	 * @generated
	 */
	protected void refreshSemantic() {
		List createdViews = new LinkedList();
		createdViews.addAll(refreshSemanticChildren());
		List createdConnectionViews = new LinkedList();
		createdConnectionViews.addAll(refreshSemanticConnections());
		createdConnectionViews.addAll(refreshConnections());

		if (createdViews.size() > 1) {
			// perform a layout of the container
			DeferredLayoutCommand layoutCmd = new DeferredLayoutCommand(host()
					.getEditingDomain(), createdViews, host());
			executeCommand(new ICommandProxy(layoutCmd));
		}

		createdViews.addAll(createdConnectionViews);
		makeViewsImmutable(createdViews);
	}

	/**
	 * @generated
	 */
	private Collection myLinkDescriptors = new LinkedList();

	/**
	 * @generated
	 */
	private Map myEObject2ViewMap = new HashMap();

	/**
	 * @generated
	 */
	private Collection refreshConnections() {
		try {
			collectAllLinks(getDiagram());
			Collection existingLinks = new LinkedList(getDiagram().getEdges());
			for (Iterator diagramLinks = existingLinks.iterator(); diagramLinks
					.hasNext();) {
				Edge nextDiagramLink = (Edge) diagramLinks.next();
				EObject diagramLinkObject = nextDiagramLink.getElement();
				EObject diagramLinkSrc = nextDiagramLink.getSource()
						.getElement();
				EObject diagramLinkDst = nextDiagramLink.getTarget()
						.getElement();
				int diagramLinkVisualID = UMLVisualIDRegistry
						.getVisualID(nextDiagramLink);
				for (Iterator modelLinkDescriptors = myLinkDescriptors
						.iterator(); modelLinkDescriptors.hasNext();) {
					LinkDescriptor nextLinkDescriptor = (LinkDescriptor) modelLinkDescriptors
							.next();
					if (diagramLinkObject == nextLinkDescriptor
							.getLinkElement()
							&& diagramLinkSrc == nextLinkDescriptor.getSource()
							&& diagramLinkDst == nextLinkDescriptor
									.getDestination()
							&& diagramLinkVisualID == nextLinkDescriptor
									.getVisualID()) {
						diagramLinks.remove();
						modelLinkDescriptors.remove();
					}
				}
			}
			deleteViews(existingLinks.iterator());
			return createConnections(myLinkDescriptors);
		} finally {
			myLinkDescriptors.clear();
			myEObject2ViewMap.clear();
		}
	}

	/**
	 * @generated
	 */
	private void collectAllLinks(View view) {
		EObject modelElement = view.getElement();
		int diagramElementVisualID = UMLVisualIDRegistry.getVisualID(view);
		switch (diagramElementVisualID) {
		case ClassEditPart.VISUAL_ID: {
			collectShortCutLinks((org.eclipse.uml2.uml.Class) modelElement);
		}
		case EnumerationEditPart.VISUAL_ID:
		case InterfaceEditPart.VISUAL_ID:
		case ActorEditPart.VISUAL_ID:
		case UseCaseEditPart.VISUAL_ID:
		case PropertyEditPart.VISUAL_ID:
		case EnumerationLiteralEditPart.VISUAL_ID:
		case OperationEditPart.VISUAL_ID:
		case PackageEditPart.VISUAL_ID: {
			myEObject2ViewMap.put(modelElement, view);
			storeLinks(modelElement, getDiagram());
		}
		default: {
		}
		
		Collection kids = new ArrayList(view.getChildren());
			for (Iterator children = kids.iterator(); children
					.hasNext();) {
				View childView = (View) children.next();
				collectAllLinks(childView);
			}
		}
	}

	private org.eclipse.uml2.uml.Package getPackage() {
		return (org.eclipse.uml2.uml.Package) getDiagram().getElement();
	}

	private void collectShortCutLinks(org.eclipse.uml2.uml.Class modelElement) {
		if (!(modelElement.getPackage().equals(getPackage()))) {
			return;
		}
		try {
			EList<Association> associations = modelElement.getAssociations();
			for (Association association : associations) {
				if (association.getRelatedElements().size() > 0) {
					Object structuralFeatureResult = association
							.getRelatedElements().get(0);
					if (structuralFeatureResult instanceof EObject) {
						EObject dst = (EObject) structuralFeatureResult;
						if (dst instanceof org.eclipse.uml2.uml.Class) {
							org.eclipse.uml2.uml.Class dst2 = (org.eclipse.uml2.uml.Class) dst;
							if (!(dst2.getPackage().equals(modelElement
									.getPackage()))) {
								if (!myEObject2ViewMap.containsKey(dst2)
										&& !isAlreadyShortCut(dst2)) {
									View view = createShortCut(dst2);
									if (view != null) {
										myEObject2ViewMap.put(dst2, view);
									}
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			UMLDiagramEditorPlugin.getInstance().logInfo(e.getMessage(), e);
		}
	}

	private boolean isAlreadyShortCut(org.eclipse.uml2.uml.Class dst2) {
		for (Iterator children = getDiagram().getChildren().iterator(); children
				.hasNext();) {
			View childView = (View) children.next();
			EObject modelElement = childView.getElement();
			if (modelElement.equals(dst2)) {
				return true;
			}
		}
		return false;
	}

	private View createShortCut(org.eclipse.uml2.uml.Class selectedElement) {
		CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(
				new EObjectAdapter(selectedElement), Node.class, null,
				UMLDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT);
		CreateCommand command = new CreateCommand(ModelUtil.getEditingDomain(),
				viewDescriptor, getDiagram()) {

			protected CommandResult doExecuteWithResult(
					IProgressMonitor monitor, IAdaptable info)
					throws ExecutionException {
				CommandResult result = super.doExecuteWithResult(monitor, info);
				View view = (View) ((IAdaptable) result.getReturnValue())
						.getAdapter(View.class);
				if (view != null && view.getEAnnotation("Shortcut") == null) { //$NON-NLS-1$
					EAnnotation shortcutAnnotation = EcoreFactory.eINSTANCE
							.createEAnnotation();
					shortcutAnnotation.setSource("Shortcut"); //$NON-NLS-1$
					shortcutAnnotation.getDetails().put(
							"modelID", PackageEditPart.MODEL_ID); //$NON-NLS-1$
					view.getEAnnotations().add(shortcutAnnotation);
				}
				return result;
			}
		};
		try {
			OperationHistoryFactory.getOperationHistory().execute(command,
					new NullProgressMonitor(), null);
			return (View) ((IAdaptable) command.getCommandResult()
					.getReturnValue()).getAdapter(View.class);
		} catch (ExecutionException e) {
			UMLDiagramEditorPlugin.getInstance().logError(
					"Unable to create shortcut", e);
			return null;
		}
	}

	/**
	 * @generated
	 */
	private Collection createConnections(Collection linkDescriptors) {
		if (linkDescriptors.isEmpty()) {
			return Collections.EMPTY_LIST;
		}
		List adapters = new LinkedList();
		for (Iterator linkDescriptorsIterator = linkDescriptors.iterator(); linkDescriptorsIterator
				.hasNext();) {
			final LinkDescriptor nextLinkDescriptor = (LinkDescriptor) linkDescriptorsIterator
					.next();
			EditPart sourceEditPart = getEditPartFor(nextLinkDescriptor
					.getSource());
			EditPart targetEditPart = getEditPartFor(nextLinkDescriptor
					.getDestination());
			if (sourceEditPart == null || targetEditPart == null) {
				continue;
			}
			CreateConnectionViewRequest.ConnectionViewDescriptor descriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(
					nextLinkDescriptor.getSemanticAdapter(), null,
					ViewUtil.APPEND, false, ((IGraphicalEditPart) getHost())
							.getDiagramPreferencesHint());
			CreateConnectionViewRequest ccr = new CreateConnectionViewRequest(
					descriptor);
			ccr.setType(RequestConstants.REQ_CONNECTION_START);
			ccr.setSourceEditPart(sourceEditPart);
			sourceEditPart.getCommand(ccr);
			ccr.setTargetEditPart(targetEditPart);
			ccr.setType(RequestConstants.REQ_CONNECTION_END);
			Command cmd = targetEditPart.getCommand(ccr);
			if (cmd != null && cmd.canExecute()) {
				executeCommand(cmd);
				IAdaptable viewAdapter = (IAdaptable) ccr.getNewObject();
				if (viewAdapter != null) {
					adapters.add(viewAdapter);
				}
			}
		}
		return adapters;
	}

	/**
	 * @generated
	 */
	private EditPart getEditPartFor(EObject modelElement) {
		View view = (View) myEObject2ViewMap.get(modelElement);
		if (view != null) {
			return (EditPart) getHost().getViewer().getEditPartRegistry().get(
					view);
		}
		return null;
	}

	/**
	 * @generated
	 */
	private void storeLinks(EObject container, Diagram diagram) {
		EClass containerMetaclass = container.eClass();
		storeFeatureModelFacetLinks(container, containerMetaclass, diagram);
		storeTypeModelFacetLinks(container, containerMetaclass);
	}

	/**
	 * @generated NOT
	 */
	private void storeTypeModelFacetLinks(EObject container,
			EClass containerMetaclass) {
		if (UMLPackage.eINSTANCE.getClassifier().isSuperTypeOf(
				containerMetaclass)) {
			for (Iterator values = ((Classifier) container)
					.getGeneralizations().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (GeneralizationEditPart.VISUAL_ID == linkVID) {
					Object structuralFeatureResult = ((Generalization) nextValue)
							.getGeneral();
					if (structuralFeatureResult instanceof EObject) {
						EObject dst = (EObject) structuralFeatureResult;
						EObject src = container;
						myLinkDescriptors.add(new LinkDescriptor(src, dst,
								nextValue, linkVID));
					}
				}
			}
		}
		if (UMLPackage.eINSTANCE.getPackage().isSuperTypeOf(containerMetaclass)) {
			for (Iterator values = ((org.eclipse.uml2.uml.Package) container)
					.getPackagedElements().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (nextValue instanceof org.eclipse.uml2.uml.Class) {
					handleShortCuts((org.eclipse.uml2.uml.Class) nextValue);
				}
				if (AssociationEditPart.VISUAL_ID == linkVID) {
					if (((Relationship) nextValue).getRelatedElements().size() > 0) {
						Object structuralFeatureResult = ((Relationship) nextValue)
								.getRelatedElements().get(0);
						if (structuralFeatureResult instanceof EObject) {
							EObject dst = (EObject) structuralFeatureResult;
							EList list = ((Relationship) nextValue)
									.getRelatedElements();
							if (list.size() == 2) {
								structuralFeatureResult = list.get(1);
							} else {
								// relationship to self
								structuralFeatureResult = list.get(0);
							}
							if (structuralFeatureResult instanceof EObject) {
								EObject src = (EObject) structuralFeatureResult;
								myLinkDescriptors.add(new LinkDescriptor(src,
										dst, nextValue, linkVID));
							}
						}
					}
				}
			}
		}
		if (UMLPackage.eINSTANCE.getPackage().isSuperTypeOf(containerMetaclass)) {
			for (Iterator values = ((org.eclipse.uml2.uml.Package) container)
					.getPackagedElements().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (Association2EditPart.VISUAL_ID == linkVID) {
					if (((Relationship) nextValue).getRelatedElements().size() > 0) {
						Object structuralFeatureResult = ((Relationship) nextValue)
								.getRelatedElements().get(0);
						if (structuralFeatureResult instanceof EObject) {
							EObject dst = (EObject) structuralFeatureResult;
							EList list = ((Relationship) nextValue)
									.getRelatedElements();
							if (list.size() == 2) {
								structuralFeatureResult = list.get(1);
							} else {
								// relationship to self
								structuralFeatureResult = list.get(0);
							}
							if (structuralFeatureResult instanceof EObject) {
								EObject src = (EObject) structuralFeatureResult;
								myLinkDescriptors.add(new LinkDescriptor(src,
										dst, nextValue, linkVID));
							}
						}
					}
				}
			}
		}
		if (UMLPackage.eINSTANCE.getPackage().isSuperTypeOf(containerMetaclass)) {
			for (Iterator values = ((org.eclipse.uml2.uml.Package) container)
					.getPackagedElements().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (Association3EditPart.VISUAL_ID == linkVID) {
					if (((Relationship) nextValue).getRelatedElements().size() > 0) {
						Object structuralFeatureResult = ((Relationship) nextValue)
								.getRelatedElements().get(0);
						if (structuralFeatureResult instanceof EObject) {
							EObject dst = (EObject) structuralFeatureResult;
							EList list = ((Relationship) nextValue)
									.getRelatedElements();
							if (list.size() == 2) {
								structuralFeatureResult = list.get(1);
							} else {
								// relationship to self
								structuralFeatureResult = list.get(0);
							}
							if (structuralFeatureResult instanceof EObject) {
								EObject src = (EObject) structuralFeatureResult;
								myLinkDescriptors.add(new LinkDescriptor(src,
										dst, nextValue, linkVID));
							}
						}
					}
				}
			}
		}
		if (UMLPackage.eINSTANCE.getPackage().isSuperTypeOf(containerMetaclass)) {
			for (Iterator values = ((org.eclipse.uml2.uml.Package) container)
					.getPackagedElements().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (Association4EditPart.VISUAL_ID == linkVID) {
					if (((Relationship) nextValue).getRelatedElements().size() > 0) {
						Object structuralFeatureResult = ((Relationship) nextValue)
								.getRelatedElements().get(0);
						if (structuralFeatureResult instanceof EObject) {
							EObject dst = (EObject) structuralFeatureResult;
							EList list = ((Relationship) nextValue)
									.getRelatedElements();
							if (list.size() == 2) {
								structuralFeatureResult = list.get(1);
							} else {
								// relationship to self
								structuralFeatureResult = list.get(0);
							}
							if (structuralFeatureResult instanceof EObject) {
								EObject src = (EObject) structuralFeatureResult;
								myLinkDescriptors.add(new LinkDescriptor(src,
										dst, nextValue, linkVID));
							}
						}
					}
				}
			}
		}
		if (UMLPackage.eINSTANCE.getPackage().isSuperTypeOf(containerMetaclass)) {
			for (Iterator values = ((org.eclipse.uml2.uml.Package) container)
					.getPackagedElements().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (Association5EditPart.VISUAL_ID == linkVID) {
					if (((Relationship) nextValue).getRelatedElements().size() > 0) {
						Object structuralFeatureResult = ((Relationship) nextValue)
								.getRelatedElements().get(0);
						if (structuralFeatureResult instanceof EObject) {
							EObject dst = (EObject) structuralFeatureResult;
							EList list = ((Relationship) nextValue)
									.getRelatedElements();
							if (list.size() == 2) {
								structuralFeatureResult = list.get(1);
							} else {
								// relationship to self
								structuralFeatureResult = list.get(0);
							}
							if (structuralFeatureResult instanceof EObject) {
								EObject src = (EObject) structuralFeatureResult;
								myLinkDescriptors.add(new LinkDescriptor(src,
										dst, nextValue, linkVID));
							}
						}
					}
				}
			}
		}
		if (UMLPackage.eINSTANCE.getPackage().isSuperTypeOf(containerMetaclass)) {
			for (Iterator values = ((org.eclipse.uml2.uml.Package) container)
					.getPackagedElements().iterator(); values.hasNext();) {
				EObject nextValue = ((EObject) values.next());
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(nextValue);
				if (DependencyEditPart.VISUAL_ID == linkVID) {
					if (((Dependency) nextValue).getSuppliers().iterator()
							.hasNext()) {
						Object structuralFeatureResult = ((Dependency) nextValue)
								.getSuppliers().iterator().next();
						if (structuralFeatureResult instanceof EObject) {
							EObject dst = (EObject) structuralFeatureResult;
							if (((Dependency) nextValue).getClients()
									.iterator().hasNext()) {
								structuralFeatureResult = ((Dependency) nextValue)
										.getClients().iterator().next();
								if (structuralFeatureResult instanceof EObject) {
									EObject src = (EObject) structuralFeatureResult;
									myLinkDescriptors.add(new LinkDescriptor(
											src, dst, nextValue, linkVID));
								}
							}
						}
					}
				}
			}
		}
	}

	private void handleShortCuts(org.eclipse.uml2.uml.Class nextValue) {
		try {
			EList<Association> associations = nextValue.getAssociations();
			for (Association association : associations) {
				int linkVID = UMLVisualIDRegistry
						.getLinkWithClassVisualID(association);
				if (((Relationship) association).getRelatedElements().size() > 0) {
					Object structuralFeatureResult = ((Relationship) association)
							.getRelatedElements().get(0);
					if (structuralFeatureResult instanceof org.eclipse.uml2.uml.Class) {
						org.eclipse.uml2.uml.Class dst = (org.eclipse.uml2.uml.Class) structuralFeatureResult;
						EList list = ((Relationship) association)
								.getRelatedElements();
						if (list.size() == 2) {
							structuralFeatureResult = list.get(1);
						} else {
							// relationship to self
							structuralFeatureResult = list.get(0);
						}
						if (structuralFeatureResult instanceof org.eclipse.uml2.uml.Class) {
							org.eclipse.uml2.uml.Class src = (org.eclipse.uml2.uml.Class) structuralFeatureResult;
							if (!(src.getPackage().equals(nextValue
									.getPackage()))) {
								myLinkDescriptors.add(new LinkDescriptor(src,
										dst, association, linkVID));
							}
						}
					}
				}
			}
		} catch (Exception e) {
			UMLDiagramEditorPlugin.getInstance().logInfo(e.getMessage(), e);
		}
	}

	/**
	 * @generated
	 */
	private void storeFeatureModelFacetLinks(EObject container,
			EClass containerMetaclass, Diagram diagram) {

	}

	/**
	 * @generated
	 */
	private Diagram getDiagram() {
		return ((View) getHost().getModel()).getDiagram();
	}

	/**
	 * @generated
	 */
	private class LinkDescriptor {

		/**
		 * @generated
		 */
		private EObject mySource;

		/**
		 * @generated
		 */
		private EObject myDestination;

		/**
		 * @generated
		 */
		private EObject myLinkElement;

		/**
		 * @generated
		 */
		private int myVisualID;

		/**
		 * @generated
		 */
		private IAdaptable mySemanticAdapter;

		/**
		 * @generated
		 */
		protected LinkDescriptor(EObject source, EObject destination,
				EObject linkElement, int linkVID) {
			this(source, destination, linkVID);
			myLinkElement = linkElement;
			mySemanticAdapter = new EObjectAdapter(linkElement);
		}

		/**
		 * @generated
		 */
		protected LinkDescriptor(EObject source, EObject destination,
				IElementType elementType, int linkVID) {
			this(source, destination, linkVID);
			myLinkElement = null;
			final IElementType elementTypeCopy = elementType;
			mySemanticAdapter = new IAdaptable() {
				public Object getAdapter(Class adapter) {
					if (IElementType.class.equals(adapter)) {
						return elementTypeCopy;
					}
					return null;
				}
			};
		}

		/**
		 * @generated
		 */
		private LinkDescriptor(EObject source, EObject destination, int linkVID) {
			mySource = source;
			myDestination = destination;
			myVisualID = linkVID;
		}

		/**
		 * @generated
		 */
		protected EObject getSource() {
			return mySource;
		}

		/**
		 * @generated
		 */
		protected EObject getDestination() {
			return myDestination;
		}

		/**
		 * @generated
		 */
		protected EObject getLinkElement() {
			return myLinkElement;
		}

		/**
		 * @generated
		 */
		protected int getVisualID() {
			return myVisualID;
		}

		/**
		 * @generated
		 */
		protected IAdaptable getSemanticAdapter() {
			return mySemanticAdapter;
		}
	}

}
